using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using ERP.ERPModels.WorkforceManage;
using ERP.RBAC;
using ERP.WorkforceManage.Dtos;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;

namespace ERP.WorkforceManage
{
    /// <summary>
    /// 班组服务实现
    /// </summary>
    public class TeamService : ApplicationService, ITeamService
    {
        private readonly IRepository<Team, int> _teamRepository;
        private readonly IRepository<TeamMember, int> _teamMemberRepository;
        private readonly IRepository<Users, int> _userRepository;
        private readonly ILogger<TeamService> _logger;

        public TeamService(
            IRepository<Team, int> teamRepository,
            IRepository<TeamMember, int> teamMemberRepository,
            IRepository<Users, int> userRepository,
            ILogger<TeamService> logger)
        {
            _teamRepository = teamRepository;
            _teamMemberRepository = teamMemberRepository;
            _userRepository = userRepository;
            _logger = logger;
        }

        /// <summary>
        /// 获取班组分页列表
        /// </summary>
        public async Task<PagedResultDto<TeamDto>> GetListAsync(GetTeamInputDto input)
        {
            var query = await _teamRepository.GetQueryableAsync();

            // 应用筛选条件
            if (!string.IsNullOrWhiteSpace(input.Keyword))
            {
                query = query.Where(x => x.TeamNumber.Contains(input.Keyword) ||
                                        x.TeamName.Contains(input.Keyword));
            }

            if (!string.IsNullOrWhiteSpace(input.TeamNumber))
            {
                query = query.Where(x => x.TeamNumber.Contains(input.TeamNumber));
            }

            if (!string.IsNullOrWhiteSpace(input.TeamName))
            {
                query = query.Where(x => x.TeamName.Contains(input.TeamName));
            }

            if (!string.IsNullOrWhiteSpace(input.TeamType))
            {
                query = query.Where(x => x.TeamType.Contains(input.TeamType));
            }

            // 应用排序
            if (!string.IsNullOrWhiteSpace(input.Sorting))
            {
                query = query.OrderBy(input.Sorting);
            }
            else
            {
                query = query.OrderByDescending(x => x.Id);
            }

            var totalCount = await query.CountAsync();
            var items = await query.Skip(input.SkipCount).Take(input.MaxResultCount).ToListAsync();

            var dtos = new List<TeamDto>();
            foreach (var item in items)
            {
                var dto = await MapToDtoAsync(item);
                dtos.Add(dto);
            }

            return new PagedResultDto<TeamDto>(totalCount, dtos);
        }

        /// <summary>
        /// 获取班组详情
        /// </summary>
        public async Task<TeamDto> GetAsync(int id)
        {
            var entity = await _teamRepository.GetAsync(id);
            return await MapToDtoAsync(entity);
        }

        /// <summary>
        /// 创建班组
        /// </summary>
        public async Task<TeamDto> CreateAsync(CreateTeamDto input)
        {
            var entity = new Team
            {
                TeamNumber = await GenerateTeamNumberAsync(),
                TeamName = input.TeamName,
                TeamType = input.TeamType,
                Descr = input.Descr
            };

            entity = await _teamRepository.InsertAsync(entity, true);

            // 添加班组成员
            await UpdateTeamMembersAsync(entity.Id, input.MemberIds);

            _logger.LogInformation("创建班组成功，ID: {Id}, 班组编号: {TeamNumber}", entity.Id, entity.TeamNumber);

            return await MapToDtoAsync(entity);
        }

        /// <summary>
        /// 更新班组
        /// </summary>
        public async Task<TeamDto> UpdateAsync(int id, UpdateTeamDto input)
        {
            var entity = await _teamRepository.GetAsync(id);

            entity.TeamName = input.TeamName;
            entity.TeamType = input.TeamType;
            entity.Descr = input.Descr;

            entity = await _teamRepository.UpdateAsync(entity, true);

            // 更新班组成员
            await UpdateTeamMembersAsync(entity.Id, input.MemberIds);

            _logger.LogInformation("更新班组成功，ID: {Id}", entity.Id);

            return await MapToDtoAsync(entity);
        }

        /// <summary>
        /// 删除班组
        /// </summary>
        public async Task DeleteAsync(int id)
        {
            // 删除班组成员关联
            var memberQuery = await _teamMemberRepository.GetQueryableAsync();
            var members = await memberQuery.Where(x => x.TeamId == id).ToListAsync();
            await _teamMemberRepository.DeleteManyAsync(members);

            // 删除班组
            await _teamRepository.DeleteAsync(id);
            _logger.LogInformation("删除班组成功，ID: {Id}", id);
        }

        /// <summary>
        /// 获取用户选择列表
        /// </summary>
        public async Task<PagedResultDto<UserSelectDto>> GetUserSelectListAsync(GetUserSelectInputDto input)
        {
            var query = await _userRepository.GetQueryableAsync();

            // 应用筛选条件
            if (!string.IsNullOrWhiteSpace(input.Keyword))
            {
                query = query.Where(x => x.Username.Contains(input.Keyword) ||
                                        x.UserNickname.Contains(input.Keyword));
            }

            // 应用排序
            if (!string.IsNullOrWhiteSpace(input.Sorting))
            {
                query = query.OrderBy(input.Sorting);
            }
            else
            {
                query = query.OrderBy(x => x.Username);
            }

            var totalCount = await query.CountAsync();
            var items = await query.Skip(input.SkipCount).Take(input.MaxResultCount).ToListAsync();

            var dtos = items.Select(x => new UserSelectDto
            {
                Id = x.Id,
                Username = x.Username,
                UserNickname = x.UserNickname,
                IsSelected = input.SelectedUserIds.Contains(x.Id)
            }).ToList();

            return new PagedResultDto<UserSelectDto>(totalCount, dtos);
        }

        /// <summary>
        /// 生成班组编号
        /// </summary>
        public async Task<string> GenerateTeamNumberAsync()
        {
            var today = DateTime.Now.ToString("yyyyMMdd");
            var prefix = $"BZ{today}";

            var query = await _teamRepository.GetQueryableAsync();
            var maxCode = await query
                .Where(x => x.TeamNumber.StartsWith(prefix))
                .Select(x => x.TeamNumber)
                .OrderByDescending(x => x)
                .FirstOrDefaultAsync();

            var sequence = 1;
            if (!string.IsNullOrEmpty(maxCode) && maxCode.Length > prefix.Length)
            {
                var sequenceStr = maxCode.Substring(prefix.Length);
                if (int.TryParse(sequenceStr, out var lastSequence))
                {
                    sequence = lastSequence + 1;
                }
            }

            return $"{prefix}{sequence:D4}";
        }

        /// <summary>
        /// 根据用户ID列表获取用户信息
        /// </summary>
        public async Task<List<UserSelectDto>> GetSelectedUsersInfoAsync(List<int> userIds)
        {
            if (userIds == null || !userIds.Any())
            {
                return new List<UserSelectDto>();
            }

            var query = await _userRepository.GetQueryableAsync();
            var users = await query
                .Where(x => userIds.Contains(x.Id))
                .Select(x => new UserSelectDto
                {
                    Id = x.Id,
                    Username = x.Username,
                    UserNickname = x.UserNickname,
                    IsSelected = true
                })
                .ToListAsync();

            return users;
        }

        /// <summary>
        /// 更新班组成员
        /// </summary>
        private async Task UpdateTeamMembersAsync(int teamId, List<int> memberIds)
        {
            try
            {
                // 删除现有成员
                var memberQuery = await _teamMemberRepository.GetQueryableAsync();
                var existingMembers = await memberQuery.Where(x => x.TeamId == teamId).ToListAsync();
                if (existingMembers.Any())
                {
                    await _teamMemberRepository.DeleteManyAsync(existingMembers);
                }

                // 添加新成员
                if (memberIds?.Any() == true)
                {
                    // 验证用户是否存在
                    var userQuery = await _userRepository.GetQueryableAsync();
                    var validUserIds = await userQuery
                        .Where(x => memberIds.Contains(x.Id))
                        .Select(x => x.Id)
                        .ToListAsync();

                    if (validUserIds.Any())
                    {
                        var newMembers = validUserIds.Select(userId => new TeamMember
                        {
                            TeamId = teamId,
                            UserId = userId
                        }).ToList();

                        await _teamMemberRepository.InsertManyAsync(newMembers);
                    }
                }

                _logger.LogInformation("更新班组成员成功，班组ID: {TeamId}, 成员数: {MemberCount}", teamId, memberIds?.Count ?? 0);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "更新班组成员失败，班组ID: {TeamId}", teamId);
                throw;
            }
        }

        /// <summary>
        /// 映射到DTO
        /// </summary>
        private async Task<TeamDto> MapToDtoAsync(Team entity)
        {
            var dto = new TeamDto
            {
                Id = entity.Id,
                TeamNumber = entity.TeamNumber,
                TeamName = entity.TeamName,
                TeamType = entity.TeamType,
                Descr = entity.Descr
            };

            // 获取班组成员
            var memberQuery = await _teamMemberRepository.GetQueryableAsync();
            var members = await memberQuery
                .Where(x => x.TeamId == entity.Id)
                .Include(x => x.User)
                .ToListAsync();

            dto.Members = members.Select(x => new TeamMemberDto
            {
                UserId = x.UserId,
                Username = x.User.Username,
                UserNickname = x.User.UserNickname
            }).ToList();

            return dto;
        }
    }
} 